package ai.koog.agents.core.feature.model.events

import ai.koog.prompt.dsl.ModerationResult
import ai.koog.prompt.dsl.Prompt
import ai.koog.prompt.message.Message
import kotlinx.datetime.Clock
import kotlinx.serialization.Serializable

/**
 * Represents an event indicating the start of a call to a Language Learning Model (LLM).
 *
 * This event captures the details of the LLM interaction at the point of invocation, including the
 * input prompt and any tools that will be used during the call. It extends the `DefinedFeatureEvent` class
 * and serves as a specific type of event in a feature-driven framework.
 *
 * @property runId A unique identifier associated with the specific run of the LLM call.
 * @property prompt The input prompt encapsulated as a [Prompt] object. This represents the structured set of
 *                  messages and configuration parameters sent to the LLM.
 * @property model The description of the LLM model used during the call. Use the format: 'llm_provider:model_id';
 * @property tools A list of tools used or invoked during the LLM call.
 * @property timestamp The timestamp of the event, in milliseconds since the Unix epoch.
 */
@Serializable
public data class LLMCallStartingEvent(
    val runId: String,
    val prompt: Prompt,
    val model: String,
    val tools: List<String>,
    override val timestamp: Long = Clock.System.now().toEpochMilliseconds(),
) : DefinedFeatureEvent()

/**
 * Represents an event signaling the completion of an LLM (Large Language Model) call.
 *
 * This event encapsulates the responses provided by the LLM during its operation. It serves as a
 * record of the responses generated by the LLM, marking the end of a particular interaction cycle.
 * The event is used within the system to capture relevant output data and ensure proper tracking
 * and logging of LLM-related interactions.
 *
 * @property runId The unique identifier of the LLM run.
 * @property prompt The input prompt encapsulated as a [Prompt] object. This represents the structured set of
 *                  messages and configuration parameters sent to the LLM.
 * @property model The description of the LLM model used during the call. Use the format: 'llm_provider:model_id';
 * @property responses A list of responses generated by the LLM, represented as instances of [Message.Response].
 *                     Each response contains content, metadata, and additional context about the interaction.
 * @property moderationResponse The moderation response, if any, returned by the LLM.
 *                              This is typically used to capture and track content moderation results.
 * @property timestamp The timestamp of the event, in milliseconds since the Unix epoch.
 */
@Serializable
public data class LLMCallCompletedEvent(
    val runId: String,
    val prompt: Prompt,
    val model: String,
    val responses: List<Message.Response>,
    val moderationResponse: ModerationResult? = null,
    override val timestamp: Long = Clock.System.now().toEpochMilliseconds(),
) : DefinedFeatureEvent()

//region Deprecated

@Deprecated(
    message = "Use LLMCallStartingEvent instead",
    replaceWith = ReplaceWith("LLMCallStartingEvent")
)
public typealias BeforeLLMCallEvent = LLMCallStartingEvent

@Deprecated(
    message = "Use LLMCallCompletedEvent instead",
    replaceWith = ReplaceWith("LLMCallCompletedEvent")
)
public typealias AfterLLMCallEvent = LLMCallCompletedEvent

//endregion Deprecated
